import re
from job import video_generator
import time
from settings import VIDEO_JOB_API_URL, MAX_RETRY, VIDEO_SAVE_API_URL, VIDEO_ADD_JOB_URL, VIDEO_DETAIL_URL, EXPIRE_DAY
from pkg.comm.global_azure_model import azure_client
from pkg.comm.global_request_api import get_video_job, save_job_api,save_video_detail,retry_add_job
import threading
import datetime
import socket
import time
worker_ip = []
# 需要把视频素材的embed序列化写到redis之后，然后执行视频生成。pkg.comm.gobal_video_embed_serialized.py


class VideoGenerator(object):
    def __init__(self):
        if azure_client.client is None:
            azure_client.reconn_client()
        self.client = azure_client.get_client()
        self.MAX_RETRY = MAX_RETRY

    def get_local_ip(self):
        if len(worker_ip) == 0:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(("8.8.8.8", 80))
            worker_ip.append(s.getsockname()[0])
        return worker_ip[0]

    def input_embedding(self, text):
        for i in range(self.MAX_RETRY):
            try:
                t1 = time.time()
                response = self.client.embeddings.create(
                    input=text,
                    model="kykembedding")
                r = response.data[0].embedding
                input_embedding_float = [float(value) for value in r]  # 转化为浮点
                t2 = time.time()
                embed_second = t2 - t1
                return True, input_embedding_float, embed_second
            except Exception as ex:
                print("retry", i, "error", ex)
                time.sleep(2)
        return False, "字幕嵌入向量失败", None

    def produce_video(self, job_id, worker_ip, content, input_ed, embed_time, init_datas):
        # 生成视频
        for i in range(self.MAX_RETRY):
            consume_second, oss_url, video_time, cover_url = video_generator.run(job_id, worker_ip, content, input_ed, embed_time, init_datas)
            if oss_url is not None and consume_second is not None:
                return True, consume_second, oss_url,video_time, cover_url, None
            if cover_url is not None:
                return False, None, None, None, None, '上传成功，但是消息推送失败'
                # 重试次数用完后直接退出循环
            if i == self.MAX_RETRY - 1:
                break
        return False, None, None, None, None, '视频生成失败'

    def get_expire_time(self, url):
        expires_pattern = r"Expires=(\d+)"
        match = re.search(expires_pattern, url)
        if match is None:
            expiration_time = datetime.datetime.now() + datetime.timedelta(days=EXPIRE_DAY)
            expire_time = expiration_time.strftime("%Y-%m-%d %H:%M:%S")
        else:
            timestamp = int(match.group(1))
            expiration_time = datetime.datetime.fromtimestamp(timestamp)
            expire_time = expiration_time.strftime("%Y-%m-%d %H:%M:%S")
        return expire_time


    def run(self):
        while True:
            res,datas, content, job_id = get_video_job(VIDEO_JOB_API_URL)
            worker_ip = self.get_local_ip()
            if not res:
                save_job_api(VIDEO_SAVE_API_URL, job_id, worker_ip, mark='没有视频任务', status='failed')
                time.sleep(5)
                continue

            result, input_ed, embed_time = self.input_embedding(content)
            embed_time = int(embed_time * 100) / 100
            if not result:
                # 嵌入向量失败
                mark = input_ed
                save_job_api(VIDEO_SAVE_API_URL, job_id, worker_ip, mark=mark, status='failed')
                save_video_detail(VIDEO_DETAIL_URL, job_id, worker_ip,mark=mark,status='failed')
                retry_add_job(VIDEO_ADD_JOB_URL, datas)
                time.sleep(5)
                continue
            save_video_detail(VIDEO_DETAIL_URL, job_id,  worker_ip, embed_seconds=embed_time,status='in_progress')


            ret, consume_second, oss_url,video_time, cover_url, video_mark = self.produce_video(job_id, worker_ip, content, input_ed, embed_time,datas)
            if not ret:
                # 视频生成失败
                print("mark", job_id, video_mark)
                save_job_api(VIDEO_SAVE_API_URL, job_id, worker_ip, mark=video_mark, status='failed')
                retry_add_job(VIDEO_ADD_JOB_URL, datas)
                continue

            print("cover_url", cover_url)
            video_time = int(video_time * 100) / 100
            expiration_time = self.get_expire_time(oss_url)

            save_job_api(VIDEO_SAVE_API_URL, job_id, worker_ip, consume_seconds=consume_second, oss_url=oss_url,
                         status='completed', video_time=video_time, is_new=True, expire_time=expiration_time,
                         cover=cover_url)


job = VideoGenerator()
job.run()
